package parking;

import parking.entity.Car;
import parking.entity.Ticket;
import parking.exception.AllParkLotIsFullException;
import parking.exception.InvalidTicketException;
import parking.service.ParkReport;

import java.util.ArrayList;
import java.util.Optional;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.Objects.requireNonNull;


public class ParkBoyManager extends ParkBoy{
    /**
     * 所掌管的所有小弟
     */
    private final List<ParkBoy> boyList;

    /**
     * 构造器
     * @param boyList 所拥有的小弟
     * @param parkLots 停车场
     */
    public ParkBoyManager(List<ParkBoy> boyList,ParkLot... parkLots) {
        super(parkLots);
        requireNonNull(boyList);
        this.boyList = boyList;
    }

    /**
     * 找车场
     *
     * @return 存放车场的容器
     */
    @Override
    protected Optional<ParkLot> findParkLot() {
        Optional<ParkLot> parkLot = lotList.stream()
                .filter(ParkLot::hasSpace).findFirst();
        if(parkLot.isPresent()){
            return parkLot;
        }
        /*Optional<ParkBoy> parkBoy = boyList.stream()
                .filter(ParkBoy -> ParkBoy.findParkLot().isPresent())
                .findFirst();
        if(parkBoy.isPresent()){
            return parkBoy.get().findParkLot();
        }
        throw new AllParkLotIsFullException();*/
        return boyList.stream().filter(boy -> boy.findParkLot().isPresent())
                .findFirst().map(boy -> boy.findParkLot().orElse(null));
    }

    @Override
    public Car take(Ticket ticket) {
        Optional<ParkLot>  parkLot = lotList.stream()
                .filter(lot -> lot.isValidTicket(ticket))
                .findFirst();
        if(parkLot.isPresent()) {
            return parkLot.get().take(ticket);
        }else{
            for (ParkBoy p: boyList) {
                Optional<ParkLot> parkLot1 = p.getLotList()
                        .stream()
                        .filter(n -> n.isValidTicket(ticket))
                        .findFirst();
                if(parkLot1.isPresent()){
                    return parkLot1.get().take(ticket);
                }
            }
        }
        throw new InvalidTicketException();
    }

   /* @Override
    public int getTotalSpace() {
        int managerTotal = super.getTotalSpace();
        for (ParkBoy p:boyList) {
            managerTotal = managerTotal + p.getTotalSpace();
        }
        return managerTotal;
    }

    @Override
    public int getExistCar() {
        int managerExist = super.getExistCar();
        for (ParkBoy p:boyList) {
            managerExist = managerExist + p.getExistCar();
        }
        return managerExist;
    }

    public List<ParkBoy> getBoyList() {
        return boyList;
    }*/

    @Override
    public String getType() {
        return "M";
    }

    @Override
    public int getHasCar() {
        int ownHasCar = super.getHasCar();
        int boyHasCar = boyList.stream()
                .mapToInt(ParkBoy::getHasCar).sum();
        return ownHasCar+boyHasCar;
    }

    @Override
    public int getTotalSpace() {
        int ownTotal = super.getTotalSpace();
        int boyTotal = boyList.stream()
                .mapToInt(ParkBoy::getTotalSpace).sum();
        return ownTotal+boyTotal;
    }


    @Override
    public List<ParkReport> getChildren() {
        /*List<ParkReport> ownList = super.getChildren();
        List<ParkReport> boyList = new ArrayList<>(this.boyList);
        ownList.addAll(boyList);
        return ownList;*/
        return Stream.concat(super.getChildren().stream() , new ArrayList<>(this.boyList).stream())
                .collect(Collectors.toList());
    }
}
